<template>
  <div class="terminal-container">
    <!-- 顶部导航栏 -->
    <div class="header-bar">
      <div class="left-actions">
        <el-button type="primary" text @click="back" class="back-button">
          <el-icon><CaretLeft /></el-icon>
          返回
        </el-button>
        <span class="page-title">终端管理</span>
      </div>
      <div class="right-actions">
        <el-tooltip content="刷新服务器列表" placement="bottom" effect="light">
          <el-button type="primary" circle @click="getServerList" :loading="isLoading">
            <el-icon><Refresh /></el-icon>
          </el-button>
        </el-tooltip>
      </div>
    </div>
      <div class="main-content">
        <!-- 左侧服务器列表 -->
        <div class="server-panel">
          <div class="panel-header">
            <el-tag type="success" class="panel-title">终端列表</el-tag>
            <el-input 
              v-model="searchKeyword" 
              placeholder="搜索服务器" 
              prefix-icon="Search"
              clearable
              class="search-input"
            />
          </div>
          <el-scrollbar height="calc(100vh - 220px)" class="server-list-scroll">
            <el-tree
              class="server-tree"
              :data="filteredServerList"
              :props="treeProps"
              default-expand-all
              :expand-on-click-node="false"
              @node-click="handleNodeClick"
              :highlight-current="true"
              node-key="id"
              :current-node-key="currentNodekey"
              ref="tree"
            >
              <template #default="{ node, data }">
                <div class="server-node">
                  <div class="server-info">
                    <el-icon><Monitor /></el-icon>
                    <span class="server-name">{{ data.name }}</span>
                  </div>
                  <el-tag size="small" effect="plain" type="info" class="ip-tag">
                    {{ data.host_ip }}
                  </el-tag>
                </div>
              </template>
            </el-tree>
          </el-scrollbar>
        </div>

        <!-- 右侧终端显示区 -->
          <div class="terminal-panel">
          <div class="terminal-header">
            <div class="terminal-info" v-if="host_ip">
              <el-tag type="info" effect="plain">{{ currentServerName }}</el-tag>
              <el-tag type="success" effect="plain">{{ host_ip }}:{{ host_port }}</el-tag>
              <el-tag type="warning" effect="plain">{{ sys_user_name }}</el-tag>
            </div>
            
            <div class="terminal-actions">
              <el-tooltip content="调整字体大小" placement="top">
                <el-dropdown @command="changeFontSize" trigger="click">
                  <el-button type="info" text>
                  </el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="small">小</el-dropdown-item>
                      <el-dropdown-item command="medium">中</el-dropdown-item>
                      <el-dropdown-item command="large">大</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </el-tooltip>
              
              <el-tooltip content="全屏显示" placement="top">
                <el-button type="info" text @click="toggleFullscreen">
                  <el-icon><FullScreen /></el-icon>
                </el-button>
              </el-tooltip>
              
              <el-tooltip content="关闭连接" placement="top">
                <el-button type="danger" text @click="terminal_close">
                  <el-icon><Close /></el-icon>
                </el-button>
              </el-tooltip>
            </div>
          </div>
          
          <div class="terminal-wrapper" ref="terminalWrapper">
            <div id="terminal" ref="terminal" class="terminal-window"></div>
          </div>

          <div class="terminal-footer">
            <!-- 添加底部操作区 -->
            <div class="bottom-actions">
              <el-button type="primary" @click="clearScreen" :disabled="!isConnected">
                <el-icon><Delete /></el-icon>
                清空屏幕
              </el-button>
              <el-button type="success" @click="sendCommand('ls -la')" :disabled="!isConnected">
                <el-icon><Files /></el-icon>
                查看文件
              </el-button>
              <el-button type="warning" @click="sendCommand('top')" :disabled="!isConnected">
                <el-icon><Cpu /></el-icon>
                系统状态
              </el-button>
              <el-button type="danger" @click="terminal_close" :disabled="!isConnected">
                <el-icon><Switch /></el-icon>
                断开连接
              </el-button>
            </div>
          </div>
        </div>
      </div>

  </div>
</template>

<script>
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';
import { mapMutations, mapState } from "vuex";
import { config } from '/src/api/index.js';
import { 
  CaretLeft, 
  Refresh, 
  Monitor, 
  Search, 
  FullScreen,
  Close,
  Delete,
  Files,
  Cpu,
  Switch
} from '@element-plus/icons-vue';

export default {
  components: {
    CaretLeft,
    Refresh,
    Monitor,
    Search,
    FullScreen,
    Close,
    Delete,
    Files,
    Cpu,
    Switch
  },
  data() {
    return {
      serverList: [],
      filteredServerList: [],
      searchKeyword: '',
      host_ip: '',
      host_port: '',
      sys_user_name: '',
      sys_user_passwd: '',
      term: null,
      ws: null,
      fitAddon: null,
      treeProps: {
        children: 'children',
        label: 'label'
      },
      currentNodekey: null,
      currentServerName: '',
      isLoading: false,
      isConnected: false,
      fontSize: 14,
      isFullscreen: false
    };
  },
  computed: {
    ...mapState({
      server: state => state.server,
      pro: state => state.pro,
    })
  },
  watch: {
    searchKeyword(val) {
      this.filterServerList();
    }
  },
  methods: {
    ...mapMutations(['servers', 'clearServers']),
    
    filterServerList() {
      if (!this.searchKeyword) {
        this.filteredServerList = this.serverList;
        return;
      }
      
      const keyword = this.searchKeyword.toLowerCase();
      
      // 简单过滤功能，可以根据需要扩展
      this.filteredServerList = this.serverList.filter(server => 
        server.name.toLowerCase().includes(keyword) || 
        server.host_ip.toLowerCase().includes(keyword)
      );
    },
    
    handleNodeClick(data) {
      this.currentServerName = data.name;
      this.getServer(data.id);
    },

    initTerminal() {
      // 清理之前的终端实例和 WebSocket 连接
      if (this.term) {
        if (this.fitAddon) {
          try {
            // 先检查插件是否已加载再卸载
            this.term.dispose();
          } catch (e) {
            console.error('终端处理错误:', e);
          }
        } else {
          this.term.dispose();
        }
        this.term = null;
        this.fitAddon = null;
      }
      if (this.ws) {
        this.ws.close();
        this.ws = null;
      }
      
      // 创建新的终端实例
      this.term = new Terminal({
        allowTransparency: true,
        cursorBlink: true,
        cursorStyle: 'underline',
        theme: {
          background: '#1e1e1e',
          cursor: '#ffffff',
          foreground: '#67c23a',
          selection: 'rgba(255, 255, 255, 0.3)',
          black: '#000000',
          red: '#e06c75',
          green: '#98c379',
          yellow: '#e5c07b',
          blue: '#61afef',
          magenta: '#c678dd',
          cyan: '#56b6c2',
          white: '#d0d0d0'
        },
        fontFamily: 'Menlo, Monaco, "Courier New", monospace',
        fontSize: this.fontSize,
        lineHeight: 1.2,
        scrollback: 1000,
      });

      // 添加自适应插件
      this.fitAddon = new FitAddon();
      this.term.loadAddon(this.fitAddon);

      // 清空并打开终端
      const terminalContainer = this.$refs.terminal;
      terminalContainer.innerHTML = '';
      this.term.open(terminalContainer);
      
      // 自适应终端大小
      this.$nextTick(() => {
        this.fitAddon.fit();
      });

      // 连接前提示信息
      this.term.write('\x1B[1;3;33m正在连接到服务器 ' + this.host_ip + '，请稍候...\x1B[0m\r\n');

      // 连接WebSocket
      const wsURL = `ws://${config.baseURL.split('//')[1]}/asset/terminal/?host_ip=${this.host_ip}&host_port=${this.host_port}&sys_user_name=${this.sys_user_name}&sys_user_passwd=${this.sys_user_passwd}`;
      this.ws = new WebSocket(wsURL);

      // WebSocket事件监听
      this.ws.onopen = () => {
        this.isConnected = true;
        this.term.onData(data => {
          const send_data = JSON.stringify({
            flag: 'entered_key',
            entered_key: data,
            cols: this.term.cols,
            rows: this.term.rows
          });
          if (this.ws.readyState === WebSocket.OPEN) {
            try {
              this.ws.send(send_data);
            } catch (e) {
              console.log('WebSocket发送错误:', e);
            }
          }
        });

        this.ws.onmessage = event => {
          this.term.write(event.data);
        };
      };

      this.ws.onerror = event => {
        this.isConnected = false;
        this.term.write('\r\n\x1B[1;3;31m连接出错！请检查网络或服务器状态。\x1B[0m\r\n');
        console.log('WebSocket错误:', event);
      };
      
      this.ws.onclose = event => {
        this.isConnected = false;
        this.term.write('\r\n\x1B[1;3;31m连接已关闭！\x1B[0m\r\n');
      };

      // 窗口大小调整事件
      window.addEventListener('resize', this.handleResize);
      
      // 首次调整大小
      this.handleResize();
    },

    handleResize() {
      if (this.fitAddon) {
        this.fitAddon.fit();
        const { cols, rows } = this.term;
        
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
          try {
            const send_data = JSON.stringify({
              flag: 'resize',
              cols: cols,
              rows: rows
            });
            this.ws.send(send_data);
          } catch (e) {
            console.log('调整大小时发生错误:', e);
          }
        }
      }
    },

    changeFontSize(size) {
      switch(size) {
        case 'small':
          this.fontSize = 12;
          break;
        case 'medium':
          this.fontSize = 14;
          break;
        case 'large':
          this.fontSize = 16;
          break;
      }
      
      if (this.term) {
        this.term.options.fontSize = this.fontSize;
        this.handleResize();
      }
    },
    
    toggleFullscreen() {
      const terminalWrapper = this.$refs.terminalWrapper;
      
      if (!this.isFullscreen) {
        if (terminalWrapper.requestFullscreen) {
          terminalWrapper.requestFullscreen();
        } else if (terminalWrapper.mozRequestFullScreen) {
          terminalWrapper.mozRequestFullScreen();
        } else if (terminalWrapper.webkitRequestFullscreen) {
          terminalWrapper.webkitRequestFullscreen();
        } else if (terminalWrapper.msRequestFullscreen) {
          terminalWrapper.msRequestFullscreen();
        }
      } else {
        if (document.exitFullscreen) {
          document.exitFullscreen();
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) {
          document.webkitExitFullscreen();
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen();
        }
      }
      
      this.isFullscreen = !this.isFullscreen;
      
      // 给浏览器一点时间来处理全屏状态变化，然后调整终端大小
      setTimeout(() => {
        this.handleResize();
      }, 100);
    },

    terminal_close() {
      if (this.ws) {
        this.ws.close();
        this.isConnected = false;
        this.term.write('\r\n\x1B[1;3;31m连接已手动关闭！\x1B[0m\r\n');
      }
    },
    
    back() {
      if (this.ws) {
        this.ws.close();
      }
      // 正确处理终端实例
      if (this.term) {
        try {
          if (this.fitAddon) {
            this.fitAddon = null;
          }
          this.term.dispose();
          this.term = null;
        } catch (e) {
          console.error('终端关闭错误:', e);
        }
      }
      this.clearServers();
      window.history.back();
    },

    async getServer(id) {
      try {
        this.isLoading = true;
        const response = await this.$api.getServer(id);
        if (response.status === 200) {
          this.host_ip = response.data.host_ip;
          this.host_port = response.data.host_port;
          this.sys_user_name = response.data.sys_user_name;
          this.sys_user_passwd = response.data.sys_user_passwd;
          this.initTerminal();
        }
      } catch (error) {
        this.$message.error('获取服务器信息失败');
        console.error('获取服务器失败:', error);
      } finally {
        this.isLoading = false;
      }
    },
    
    async getServerList() {
      try {
        this.isLoading = true;
        const response = await this.$api.getServers(this.pro.id, 1);
        if (response.status === 200) {
          this.serverList = response.data.result;
          this.filteredServerList = this.serverList;
          
          if (this.server) {
            this.getServer(this.server);
            this.currentNodekey = this.server;
            this.$nextTick(() => {
              if (this.$refs.tree) {
                this.$refs.tree.setCurrentKey(this.currentNodekey);
                
                // 获取当前服务器名称
                const currentServer = this.serverList.find(s => s.id === this.currentNodekey);
                if (currentServer) {
                  this.currentServerName = currentServer.name;
                }
              }
            });
          }
        }
      } catch (error) {
        this.$message.error('获取服务器列表失败');
        console.error('获取服务器列表失败:', error);
      } finally {
        this.isLoading = false;
      }
    },

    clearScreen() {
      if (this.term) {
        this.term.clear();
      }
    },
    
    sendCommand(command) {
      if (this.term && this.ws && this.ws.readyState === WebSocket.OPEN && this.isConnected) {
        // 先显示要执行的命令
        this.term.write(`\r\n${command}\r\n`);
        
        // 发送命令到服务器
        const send_data = JSON.stringify({
          flag: 'entered_key',
          entered_key: command + '\r',
          cols: this.term.cols,
          rows: this.term.rows
        });
        
        try {
          this.ws.send(send_data);
        } catch (e) {
          console.log('发送命令时出错:', e);
          this.term.write('\r\n\x1B[1;3;31m发送命令失败\x1B[0m\r\n');
        }
      } else {
        this.$message.warning('终端未连接，无法发送命令');
      }
    },
  },
  created() {
    this.getServerList();
  },
  beforeUnmount() {
    // 移除事件监听器
    window.removeEventListener('resize', this.handleResize);
    
    // 关闭WebSocket连接
    if (this.ws) {
      this.ws.close();
    }
    
    // 小心处理终端实例
    if (this.term) {
      try {
        if (this.fitAddon) {
          this.fitAddon = null;
        }
        this.term.dispose();
      } catch (e) {
        console.error('卸载终端错误:', e);
      }
    }
  }
};
</script>

<style scoped>
.terminal-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f7fa;
  overflow: hidden;
}

.header-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 20px;
  background-color: #ffffff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  z-index: 10;
  flex-shrink: 0;
}

.left-actions, .right-actions {
  display: flex;
  align-items: center;
}

.page-title {
  font-size: 18px;
  font-weight: 600;
  margin-left: 15px;
  color: #303133;
}

.back-button {
  font-size: 14px;
}

.main-scrollbar {
  height: calc(100vh - 80px);
  flex: 1;
}

.main-content {
  display: flex;
  min-height: calc(100vh - 80px);
  padding-bottom: 20px;
}

.server-panel {
  width: 280px;
  background-color: #ffffff;
  border-right: 1px solid #ebeef5;
  display: flex;
  flex-direction: column;
  transition: width 0.3s;
}

.panel-header {
  padding: 15px;
  border-bottom: 1px solid #ebeef5;
}

.panel-title {
  display: block;
  width: 100%;
  text-align: center;
  margin-bottom: 15px;
  font-size: 16px;
  padding: 4px 0;
}

.search-input {
  margin-top: 10px;
}

.server-list-scroll {
  flex: 1;
}

.server-tree {
  padding: 10px;
}

.server-node {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 5px 0;
  flex-wrap: nowrap;
  min-width: 0;
}

.server-info {
  display: flex;
  align-items: center;
  overflow: hidden;
  flex: 1;
  margin-right: 8px;
}

.server-name {
  margin-left: 8px;
  font-weight: 500;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.ip-tag {
  font-size: 12px;
  white-space: nowrap;
  flex-shrink: 0;
}

.terminal-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: #ffffff;
  border-radius: 4px;
  margin: 10px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

.terminal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px 15px;
  border-bottom: 1px solid #ebeef5;
}

.terminal-info {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.terminal-actions {
  display: flex;
  gap: 5px;
}

.terminal-wrapper {
  flex: 1;
  position: relative;
  background-color: #1e1e1e;
  padding: 0;
  overflow: hidden;
  min-height: 300px;
}

.terminal-window {
  height: 100%;
  width: 100%;
}

.terminal-footer {
  padding: 20px;
  border-top: 1px solid #ebeef5;
}

.bottom-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 15px;
  justify-content: center;
}

/* 全屏样式 */
.terminal-wrapper:fullscreen {
  background-color: #1e1e1e;
  padding: 20px;
}

.terminal-wrapper:fullscreen .terminal-window {
  height: 100%;
  width: 100%;
}

@media (max-width: 768px) {
  .server-panel {
    width: 200px;
  }
  
  .terminal-info {
    flex-direction: column;
    gap: 5px;
  }
  
  .bottom-actions {
    flex-direction: column;
    align-items: stretch;
  }
}
</style>
